package com.zrb.discover.widget;

import com.zrb.mobile.R;

import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.widget.AbsListView;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListView;

public class PullToZoomListView extends ListView implements
		AbsListView.OnScrollListener {
	private static final int INVALID_VALUE = -1;
	private static final String LOG_TAG = "PullToZoomListView";
	private OnRefreshListener mRefreshListener;
	private final float REFRESH_SCALE = 1.10F;
	private static final Interpolator sInterpolator = new Interpolator() {
		public float getInterpolation(float paramAnonymousFloat) {
			float f = paramAnonymousFloat - 1.0F;
			return 1.0F + f * (f * (f * (f * f)));
		}
	};
	int mActivePointerId = -1;
	private FrameLayout mHeaderContainer;
	private int mHeaderHeight;
	float mLastMotionY = -1.0F;
	float mLastScale = -1.0F;
	float mMaxScale = -1.0F;
	private AbsListView.OnScrollListener mOnScrollListener;
	private ScalingRunnalable mScalingRunnalable;
	private int mScreenHeight;
	private ImageView mShadow;

	private boolean mScrollable = true;
	private boolean mShowHeaderImage = true;
	private boolean mZoomable = true;
	private ImageView mHeadView = null;
	private Context mContext;
	private View mShowDiscription = null;
	private int firstVisibleItem;
	private int scrollState;
	private boolean loadEnable = true;
	private boolean isLoading;
	private boolean isRefresh = false;
	private View mFooter;
	private OnLoadListener onLoadListener;
	private boolean isLoadFull = false;
	private int pageSize = 10;
	private static final float MAX_PULL_SCALE = 1.25f;
	
	public PullToZoomListView(Context paramContext) {
		super(paramContext);
		init(paramContext);
	}

	public PullToZoomListView(Context paramContext,
			AttributeSet paramAttributeSet) {
		super(paramContext, paramAttributeSet);
		init(paramContext);
	}

	public PullToZoomListView(Context paramContext,
			AttributeSet paramAttributeSet, int paramInt) {
		super(paramContext, paramAttributeSet, paramInt);
		init(paramContext);
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	private void endScraling() {
		if (this.mHeaderContainer.getBottom() >= this.mHeaderHeight)
			Log.d("mmm", "endScraling");
		this.mScalingRunnalable.startAnimation(200L);
	}

	public void addHeadView(View showDescription, View titleView) {
		mShowDiscription = showDescription;
		this.mHeaderContainer.addView(showDescription);
		// this.mShadow = new ImageView(mContext);
		// FrameLayout.LayoutParams localLayoutParams = new
		// FrameLayout.LayoutParams(
		// -1, -2);
		// localLayoutParams.gravity = 80;
		// this.mShadow.setLayoutParams(localLayoutParams);
	}

	private void init(Context paramContext) {
		super.setOnScrollListener(this);
		mContext = paramContext;
		DisplayMetrics localDisplayMetrics = new DisplayMetrics();
		((Activity) mContext).getWindowManager().getDefaultDisplay()
				.getMetrics(localDisplayMetrics);
		this.mScreenHeight = localDisplayMetrics.heightPixels;
		this.mHeaderContainer = new FrameLayout(mContext);
		this.mHeadView = new ImageView(mContext);
		int i = localDisplayMetrics.widthPixels;
		setHeaderViewSize(i, (int) getContext().getResources().getDimension(R.dimen.user_detail_head_hei));
		this.mHeaderContainer.addView(this.mHeadView);
		addHeaderView(this.mHeaderContainer);
		this.mScalingRunnalable = new ScalingRunnalable();
		super.setOnScrollListener(this);
	}

	private void onSecondaryPointerUp(MotionEvent paramMotionEvent) {
		int i = (paramMotionEvent.getAction()) >> 8;
		Log.d("onSecondaryPointerUp", i + "");
		if (paramMotionEvent.getPointerId(i) == this.mActivePointerId)
			if (i != 0) {
				this.mLastMotionY = paramMotionEvent.getY(1);
				this.mActivePointerId = paramMotionEvent.getPointerId(0);
				return;
			}
	}

	private void reset() {
		this.mActivePointerId = -1;
		this.mLastMotionY = -1.0F;
		this.mMaxScale = -1.0F;
		this.mLastScale = -1.0F;
	}

	public ImageView getHeaderView() {
		return this.mHeadView;
	}

	public void hideHeaderImage() {
		this.mShowHeaderImage = false;
		this.mZoomable = false;
		this.mScrollable = false;
		removeHeaderView(this.mHeaderContainer);
	}

	public boolean isScrollable() {
		return this.mScrollable;
	}

	public boolean isZoomable() {
		return this.mZoomable;
	}

	public boolean onInterceptTouchEvent(MotionEvent paramMotionEvent) {
		if (!this.mZoomable) {
			return super.onInterceptTouchEvent(paramMotionEvent);
		}
		switch (paramMotionEvent.getAction() & MotionEvent.ACTION_MASK) {
		case MotionEvent.ACTION_DOWN:

			this.mActivePointerId = paramMotionEvent.getPointerId(0);
			this.mMaxScale = (this.mScreenHeight / this.mHeaderHeight);
			break;

		case MotionEvent.ACTION_UP:
			reset();
			break;

		case MotionEvent.ACTION_POINTER_DOWN:
			this.mActivePointerId = paramMotionEvent
					.getPointerId(paramMotionEvent.getActionIndex());
			break;

		case MotionEvent.ACTION_POINTER_UP:
			onSecondaryPointerUp(paramMotionEvent);
			break;
		}
		return super.onInterceptTouchEvent(paramMotionEvent);
	}

	protected void onLayout(boolean paramBoolean, int paramInt1, int paramInt2,
			int paramInt3, int paramInt4) {
		super.onLayout(paramBoolean, paramInt1, paramInt2, paramInt3, paramInt4);
		if (mHeaderContainer != null && this.mHeaderHeight == 0) {
			this.mHeaderHeight = this.mHeaderContainer.getHeight();
		}
	}

	@Override
	public void onScroll(AbsListView paramAbsListView, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {
		// Log.d(LOG_TAG, "onScroll mHeaderContainer:" + mHeaderContainer);
		pullToScale(paramAbsListView, firstVisibleItem, visibleItemCount, totalItemCount);
	}

	
	private void pullToScale(AbsListView paramAbsListView, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {
		if (mHeaderContainer == null) {
			return;
		}
		if (this.mScrollable) {
			int bottomY = this.mHeaderContainer.getBottom();
			float f = this.mHeaderHeight - bottomY;
//			Log.d("scrollhei", "f|" + f);
//			Log.d("scrollRatio", "bottomY:" + bottomY);
			if ((f > 0.0F) && (f < this.mHeaderHeight)) {
//				Log.d(LOG_TAG, "onScroll 1");
				int i = (int) (0.65D * f);
				this.mHeaderContainer.scrollTo(0, -i);
				notifyHeadAlphaChanged(firstVisibleItem, bottomY);
			} else if (this.mHeaderContainer != null
					&& this.mHeaderContainer.getScrollY() != 0) {
				Log.d(LOG_TAG, "onScroll 2");
				this.mHeaderContainer.scrollTo(0, 0);
			} else if (f < 0.0F) {
				int i = (int) (0.65D * f);
				if (mShowDiscription != null) {
					this.mShowDiscription.scrollTo(0, (int) f);
				}
			}

		}

		if (this.mOnScrollListener != null) {
			this.mOnScrollListener.onScroll(paramAbsListView, firstVisibleItem,
					visibleItemCount, totalItemCount);
		}
	}

	private void notifyHeadAlphaChanged(int firstVisibleItem, int bottomY) {
		if(this.mHeaderHeight != 0){
			float titleBarHei = getContext().getResources().getDimension(R.dimen.title_bar_height_no_tab);
			float hei = bottomY - titleBarHei;
			if(mHeadScrollInterface != null){
				float ratio = 1 -  hei / (float)(this.mHeaderHeight - titleBarHei);
				if(ratio > 1){
					ratio = 1;
				}
				if(firstVisibleItem != 0){
					ratio = 1;
				}
				mHeadScrollInterface.onHeadScroll(ratio);
			}
		}
	}

	public void onScrollStateChanged(AbsListView paramAbsListView, int scrollState) {
		if (this.mOnScrollListener != null) {
			this.mOnScrollListener.onScrollStateChanged(paramAbsListView,
					scrollState);
		}
		this.scrollState = scrollState;
		ifNeedLoad(paramAbsListView, scrollState);
	}
	
	private void ifNeedLoad(AbsListView view, int scrollState) {
		Log.d(LOG_TAG,"ifNeedLoad loadEnable:" + loadEnable);
		if (!loadEnable) {
			return;
		}
		try {
			Log.d(LOG_TAG,"ifNeedLoad isLoading:" + isLoading);
			if (scrollState == OnScrollListener.SCROLL_STATE_IDLE
					&& !isLoading()
					&& view.getLastVisiblePosition() == view
							.getPositionForView(mFooter) && !isLoadFull && !isRefreshing()) {
				onLoad();
				startLoading();
			}
		} catch (Exception e) {
		}
	}

	public boolean onTouchEvent(MotionEvent ev) {

		Log.d(LOG_TAG, "" + (0xFF & ev.getAction()));
		if (!this.mZoomable) {
			Log.i("zoom", "zoom");
			return super.onTouchEvent(ev);
		}
		switch (ev.getAction() & MotionEvent.ACTION_MASK) {
		case MotionEvent.ACTION_OUTSIDE:
		case MotionEvent.ACTION_DOWN:
			if (mScalingRunnalable != null
					&& !this.mScalingRunnalable.mIsFinished) {
				this.mScalingRunnalable.abortAnimation();
			}
			this.mLastMotionY = ev.getY();
			this.mActivePointerId = ev.getPointerId(0);
			this.mMaxScale = (this.mScreenHeight / this.mHeaderHeight);
			this.mLastScale = (this.mHeaderContainer.getBottom() / this.mHeaderHeight);
			break;
		case MotionEvent.ACTION_MOVE:
			Log.d("onTouchEvent", "mActivePointerId" + mActivePointerId);
			int j = ev.findPointerIndex(this.mActivePointerId);
			if (j == -1) {
				Log.e("PullToZoomListView", "Invalid pointerId="
						+ this.mActivePointerId + " in onTouchEvent");
			} else {
				if (this.mLastMotionY == -1.0F){
					this.mLastMotionY = ev.getY(j);
				}
				if (this.mHeaderContainer.getBottom() >= this.mHeaderHeight && 
						this.mLastScale < MAX_PULL_SCALE) {
					ViewGroup.LayoutParams localLayoutParams = this.mHeaderContainer
							.getLayoutParams();
					float f = ((ev.getY(j) - this.mLastMotionY + this.mHeaderContainer
							.getBottom()) / this.mHeaderHeight - this.mLastScale)
							/ 2.0F + this.mLastScale;
					if ((this.mLastScale <= 1.0D) && (f < this.mLastScale)) {
						localLayoutParams.height = this.mHeaderHeight;
						this.mHeaderContainer
								.setLayoutParams(localLayoutParams);
					}
					this.mLastScale = Math.min(Math.max(f, 1.0F),
							this.mMaxScale);
					localLayoutParams.height = ((int) (this.mHeaderHeight * this.mLastScale));
					if (localLayoutParams.height < this.mScreenHeight)
						this.mHeaderContainer
								.setLayoutParams(localLayoutParams);
					this.mLastMotionY = ev.getY(j);
				}
				this.mLastMotionY = ev.getY(j);
			}
			break;
		case MotionEvent.ACTION_UP:
			finishPull();
			reset();
			endScraling();
			break;
		case MotionEvent.ACTION_CANCEL:

			break;
		case MotionEvent.ACTION_POINTER_DOWN:
			int i = ev.getActionIndex();
			this.mLastMotionY = ev.getY(i);
			this.mActivePointerId = ev.getPointerId(i);
			break;
		case MotionEvent.ACTION_POINTER_UP:
			onSecondaryPointerUp(ev);
			this.mLastMotionY = ev.getY(ev
					.findPointerIndex(this.mActivePointerId));
			break;
		}
		return super.onTouchEvent(ev);
	}

	public void setHeaderViewSize(int width, int height) {
		if (!this.mShowHeaderImage) {
			return;
		}
		Object localObject = this.mHeaderContainer.getLayoutParams();
		if (localObject == null)
			localObject = new AbsListView.LayoutParams(width, height);
		((ViewGroup.LayoutParams) localObject).width = width;
		((ViewGroup.LayoutParams) localObject).height = height;
		this.mHeaderContainer
				.setLayoutParams((ViewGroup.LayoutParams) localObject);
		this.mHeaderHeight = height;
	}

	public void setOnScrollListener(
			AbsListView.OnScrollListener paramOnScrollListener) {
		this.mOnScrollListener = paramOnScrollListener;
	}

	public void setScrollable(boolean paramBoolean) {
		if (!this.mShowHeaderImage) {
			return;
		}
		this.mScrollable = paramBoolean;
	}

	public void setShadow(int paramInt) {
		if (!this.mShowHeaderImage) {
			return;
		}
		this.mShadow.setBackgroundResource(paramInt);
	}

	public void setZoomable(boolean paramBoolean) {
		if (!this.mShowHeaderImage) {
			return;
		}
		this.mZoomable = paramBoolean;
	}

	class ScalingRunnalable implements Runnable {
		long mDuration;
		boolean mIsFinished = true;
		float mScale;
		long mStartTime;

		ScalingRunnalable() {
		}

		public void abortAnimation() {
			this.mIsFinished = true;
		}

		public boolean isFinished() {
			return this.mIsFinished;
		}

		public void run() {
			float f2;
			ViewGroup.LayoutParams localLayoutParams;
			if ((!this.mIsFinished) && (this.mScale > 1.0D)) {
				float f1 = ((float) SystemClock.currentThreadTimeMillis() - (float) this.mStartTime)
						/ (float) this.mDuration;
				f2 = this.mScale - (this.mScale - 1.0F)
						* PullToZoomListView.sInterpolator.getInterpolation(f1);
				localLayoutParams = PullToZoomListView.this.mHeaderContainer
						.getLayoutParams();
				if (f2 > 1.0F) {
					Log.d("mmm", "f2>1.0");
					localLayoutParams.height = PullToZoomListView.this.mHeaderHeight;
					localLayoutParams.height = ((int) (f2 * PullToZoomListView.this.mHeaderHeight));
					PullToZoomListView.this.mHeaderContainer
							.setLayoutParams(localLayoutParams);
					PullToZoomListView.this.post(this);
					return;
				}
				this.mIsFinished = true;
			}
		}

		public void startAnimation(long paramLong) {
			this.mStartTime = SystemClock.currentThreadTimeMillis();
			this.mDuration = paramLong;
			this.mScale = ((float) (PullToZoomListView.this.mHeaderContainer
					.getBottom()) / PullToZoomListView.this.mHeaderHeight);
			this.mIsFinished = false;
			PullToZoomListView.this.post(this);
		}
	}

	public void setOnRefreshListener(OnRefreshListener l) {
		mRefreshListener = l;
	}

	public interface OnRefreshListener {
		void onRefresh();
	}

	private void finishPull() {
		if (mHeaderContainer.getBottom() > mHeaderHeight) {
			if (mLastScale > REFRESH_SCALE && !isLoading() && !isRefreshing()) {
				if (mRefreshListener != null) {
					mRefreshListener.onRefresh();
				}
			}

		}
	}

	public void setOnLoadListener(OnLoadListener onLoadListener) {
		this.loadEnable = true;
		this.onLoadListener = onLoadListener;
	}

	public boolean isLoadEnable() {
		return loadEnable;
	}

	// 这里的开启或者关闭加载更多，并不支持动态调整
	public void setLoadEnable(boolean loadEnable) {
		this.loadEnable = loadEnable;
		this.removeFooterView(mFooter);
	}

	public void removeFooterView(){
		this.removeFooterView(mFooter);
	}
	
	public void addFooter(View view) {
		mFooter = view;
		this.addFooterView(mFooter);
	}

	public void addFooter() {
	}
	
	public void onLoad() {
		if (onLoadListener != null) {
			onLoadListener.onLoadMore();
		}
	}

	public interface OnLoadListener {
		public void onLoadMore();
	}

	public void loadComplete() {
		isLoading = false;
	}


	public boolean isRefreshing(){
		return isRefresh;
	}
	
	public boolean isLoading(){
		return isLoading;
	}
	
	public void startLoading(){
		isLoading = true;
	}
	
	public void startRefresh(){
		isRefresh = true;
	}
	
	public void refreshComplete(){
		isRefresh = false;
	}
	
//	public void setResultSize(int resultSize) {
//		if (resultSize == 0) {
//			isLoadFull = true;
//			mFooter.setVisibility(View.GONE);
//		} else if (resultSize > 0 && resultSize < pageSize) {
//			isLoadFull = true;
//			mFooter.setVisibility(View.GONE);
//		} else if (resultSize == pageSize) {
//			isLoadFull = false;
//			mFooter.setVisibility(View.VISIBLE);
//		}

//	}

	public interface HeadScrollInterface{
		public void onHeadScroll(float value);
	}
	
	private HeadScrollInterface mHeadScrollInterface = null;
	
	public void setHeadScrollInterface(HeadScrollInterface headScrollInterface){
		mHeadScrollInterface = headScrollInterface;
	}
	
	
	
}